package com.parsifal.bluetoothdemo;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.CompoundButton;

import com.parsifal.bluetoothdemo.listener.OnSocketReceiveListener;
import com.parsifal.bluetoothdemo.listener.OnSocketSendListener;
import com.parsifal.bluetoothdemo.iface.IBluetoothModel;
import com.parsifal.bluetoothdemo.iface.IBluetoothView;
import com.parsifal.bluetoothdemo.iface.IBluetoothViewCallback;
import com.parsifal.bluetoothdemo.ui.ChoiceDialog;
import com.parsifal.bluetoothdemo.ui.ClientDialog;
import com.parsifal.bluetoothdemo.ui.DevicesAdapter;

import java.util.ArrayList;

import static android.app.Activity.RESULT_OK;

/**
 * Created by yangming on 17-3-30.
 */
public class BluetoothPresenter implements IBluetoothViewCallback {

    private static final String TAG = "BluetoothPresenter";

    private IBluetoothModel mBluetoothModel = null;

    private IBluetoothView mBluetoothView = null;

    private ArrayList<BluetoothDevice> mDevices = null;

    private boolean isServerModel = false;

    private BluetoothDevice mSelectedDevice = null;

    public BluetoothPresenter(IBluetoothView view) {
        mBluetoothView = view;
        mBluetoothModel = new BluetoothModel();
        mDevices = new ArrayList<>();
        boolean isSuccess = mBluetoothModel.init();
        if (!isSuccess) {
            mBluetoothView.showToast("不支持蓝牙");
            return;
        }
        mBluetoothModel.createClient(new OnSocketSendListener() {
            @Override
            public void onSend(final String msg) {
                Log.e(TAG, "Client onSend " + msg);
                mBluetoothView.postRunnable(new Runnable() {
                    @Override
                    public void run() {
                        mBluetoothView.addClientMessage(msg);
                    }
                });
            }
        }, new OnSocketReceiveListener() {
            @Override
            public void onReceive(final String msg) {
                Log.e(TAG, "Client onReceive " + msg);
                mBluetoothView.postRunnable(new Runnable() {
                    @Override
                    public void run() {
                        mBluetoothView.addServerMessage(msg);
                    }
                });
            }
        });
        mBluetoothModel.createServer(new OnSocketSendListener() {
            @Override
            public void onSend(String msg) {
                Log.e(TAG, "Server onSend " + msg);
            }
        }, new OnSocketReceiveListener() {
            @Override
            public void onReceive(String msg) {
                Log.e(TAG, "Server onReceive " + msg);
            }
        });
    }

    @Override
    public void onWidgetsInitialized() {
        if (mBluetoothModel.isEnabled()) {
            mBluetoothView.enabledSearchButton();
        } else {
            mBluetoothView.disabledSearchButton();
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_open_bt:
                mBluetoothModel.open((Activity) mBluetoothView);
                break;
            case R.id.btn_search_devices:
                mDevices.clear();
                mBluetoothView.clearListView();
                mBluetoothView.showProgressBar();
                mBluetoothView.updateListView(new ArrayList<>(mBluetoothModel.getBondedDevices()));
                mBluetoothView.setHighLight(new ArrayList<>(mBluetoothModel.getBondedDevices()));
                mBluetoothModel.ensureDiscoverable((Context) mBluetoothView);
                mBluetoothModel.scan();
                break;
            case R.id.btn_connect:
                mBluetoothModel.connectServer(mSelectedDevice);
                mBluetoothView.dismissChoiceDialog();
                break;
            case R.id.btn_removebond:
                mBluetoothModel.removeBond(mSelectedDevice);
                mBluetoothView.dismissChoiceDialog();
                break;
            case R.id.btn_send:
                String msg = mBluetoothView.getEditText();
                mBluetoothModel.sendToServer(msg);
                break;
            default:
                break;
        }
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked) {
            mBluetoothView.showToast("客户端模式");
            isServerModel = false;
            mBluetoothModel.stopServer();
        } else {
            mBluetoothView.showToast("服务器模式");
            isServerModel = true;
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        DevicesAdapter adapter = (DevicesAdapter) parent.getAdapter();
        BluetoothDevice device = (BluetoothDevice) adapter.getItem(position);
        int state = device.getBondState();
        switch (state) {
            case BluetoothDevice.BOND_NONE:
                Log.d(TAG, "发起配对");
                device.createBond();
                break;
            case BluetoothDevice.BOND_BONDING:
                Log.d(TAG, "正在配对");
                break;
            case BluetoothDevice.BOND_BONDED:
                Log.d(TAG, "选择操作");
                mSelectedDevice = device;
                mBluetoothView.showChoiceDialog();
                break;
            default:
                break;
        }
    }

    @Override
    public void onDismiss(DialogInterface dialog, int id) {
        switch (id) {
            case ChoiceDialog.ID:
                break;
            case ClientDialog.ID:
                mBluetoothModel.stopClient();
                break;
            default:
                break;
        }
    }

    @Override
    public void onDestroy() {
        mBluetoothModel.disable();
        if (isServerModel) {
            mBluetoothModel.stopServer();
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == IBluetoothModel.REQUEST_ENABLE_BT) {
            if (resultCode == RESULT_OK) {
                mBluetoothView.showToast("蓝牙已经开启");
            }
        }
    }

    @Override
    public void onStart() {
        IntentFilter searchFilter = new IntentFilter();
        searchFilter.addAction(BluetoothDevice.ACTION_FOUND);
        searchFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        ((Context) mBluetoothView).registerReceiver(mSearchReceiver, searchFilter);

        IntentFilter stateChangeFilter = new IntentFilter();
        stateChangeFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        ((Context) mBluetoothView).registerReceiver(mStateChangeReceiver, stateChangeFilter);

        IntentFilter pairingFilter = new IntentFilter();
        pairingFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        ((Context) mBluetoothView).registerReceiver(mPairingReceiver, pairingFilter);

        IntentFilter connectFilter = new IntentFilter();
        connectFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
        connectFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        ((Context) mBluetoothView).registerReceiver(mConnectReceiver, connectFilter);
    }

    @Override
    public void onStop() {
        ((Context) mBluetoothView).unregisterReceiver(mSearchReceiver);
        ((Context) mBluetoothView).unregisterReceiver(mStateChangeReceiver);
        ((Context) mBluetoothView).unregisterReceiver(mPairingReceiver);
        ((Context) mBluetoothView).unregisterReceiver(mConnectReceiver);
    }

    private BroadcastReceiver mSearchReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            switch (action) {
                case BluetoothDevice.ACTION_FOUND:
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    if (!mDevices.contains(device)) {
                        mDevices.add(device);
                    }
                    break;
                case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
                    if (mDevices.size() == 0) {
                        mBluetoothView.showToast("没有搜索到设备");
                    } else {
                        mBluetoothView.updateListView(mDevices);
                    }
                    mBluetoothView.dismissProgressBar();
                    break;
                default:
                    break;
            }
        }
    };

    private BroadcastReceiver mStateChangeReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
                int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
                switch (blueState) {
                    case BluetoothAdapter.STATE_TURNING_ON:
                        Log.e(TAG, "onReceive---------STATE_TURNING_ON");
                        break;
                    case BluetoothAdapter.STATE_ON:
                        Log.e(TAG, "onReceive---------STATE_ON");
                        mBluetoothView.enabledSearchButton();
                        break;
                    case BluetoothAdapter.STATE_TURNING_OFF:
                        Log.e(TAG, "onReceive---------STATE_TURNING_OFF");
                        break;
                    case BluetoothAdapter.STATE_OFF:
                        Log.e(TAG, "onReceive---------STATE_OFF");
                        mBluetoothView.disabledSearchButton();
                        break;
                }
            }
        }
    };

    private BroadcastReceiver mPairingReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
                switch (state) {
                    case BluetoothDevice.BOND_NONE:
                        Log.d(TAG, "BOND_NONE 删除配对");
                        mBluetoothView.setHighLight(new ArrayList<BluetoothDevice>());
                        break;
                    case BluetoothDevice.BOND_BONDING:
                        Log.d(TAG, "BOND_BONDING 正在配对");
                        break;
                    case BluetoothDevice.BOND_BONDED:
                        Log.d(TAG, "BOND_BONDED 配对成功");
                        ArrayList<BluetoothDevice> devices = new ArrayList<>();
                        devices.add(device);
                        mBluetoothView.setHighLight(devices);
                        break;
                }
            }
        }
    };

    private BroadcastReceiver mConnectReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            switch (action) {
                case BluetoothDevice.ACTION_ACL_CONNECTED:
                    final BluetoothDevice device1 = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    Log.d(TAG, " ACTION_ACL_CONNECTED " + device1.getName());
                    if (isServerModel) {
                        mBluetoothModel.connectClient(device1);
                    } else {
                        if (BluetoothDevice.BOND_BONDED == device1.getBondState()) {
                            mBluetoothView.showClientDialog();
                        }
                    }
                    break;
                case BluetoothDevice.ACTION_ACL_DISCONNECTED:
                    final BluetoothDevice device2 = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    Log.d(TAG, " ACTION_ACL_DISCONNECTED " + device2.getName());
                    if (isServerModel) {
                        mBluetoothModel.closeServerSocket(device2);
                    } else {
                        mBluetoothView.dismissClientDialog();
                        mBluetoothModel.stopClient();
                    }
                    break;
                default:
                    break;
            }
        }
    };
}
